﻿
#include <windows.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Devices.Radios.h>
#include <winrt/Windows.Devices.Bluetooth.h>
#include <winrt/Windows.Devices.Bluetooth.Advertisement.h>
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.UI.Core.h>
#ifndef FLUTTER_BLUE_UTILS_H
#define FLUTTER_BLUE_UTILS_H

#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Devices.Bluetooth.GenericAttributeProfile.h> // 添加这一行
#include <winrt/base.h>
#include <vector>
#include <cstdint>
#include <sstream>
#include <iomanip>

using namespace winrt::Windows::Storage::Streams;
using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile; // 使用命名空间
using namespace winrt::Windows::Devices::Bluetooth::Advertisement;
static constexpr char GUID_FORMAT[] = "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx";
#define GUID_ARG(guid) guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]

union uint16_t_union {
    uint16_t uint16;
    byte bytes[sizeof(uint16_t)];
};
class Utils {
private:
    Utils() = delete; // 禁止实例化

public:
    // 静态工具方法定义
    inline static int utilityMethod(int a, int b) {
        return a + b; // 假设这是一个简单的加法操作
    }

    static std::vector <uint8_t> to_bytevc(winrt::Windows::Storage::Streams::IBuffer buffer) {
        auto reader = DataReader::FromBuffer(buffer);
        auto result = std::vector<uint8_t>(reader.UnconsumedBufferLength());
        reader.ReadBytes(result);
        return result;
    }

    static winrt::Windows::Storage::Streams::IBuffer from_bytevc(std::vector <uint8_t> bytes) {
        auto writer = DataWriter();
        writer.WriteBytes(bytes);
        return writer.DetachBuffer();
    }


    // 辅助函数：将字符串转换为 winrt::guid
    static winrt::guid string_to_guid(const std::string &str) {
        // 确保字符串是以 L"..." 形式的宽字符字符串
        std::wstring wideStr;
        wideStr.assign(str.begin(), str.end());

        // 创建 GUID 变量
        GUID guid;
        HRESULT hr = CLSIDFromString(const_cast<wchar_t *>(wideStr.c_str()), &guid);

        if (FAILED(hr)) {
            return winrt::guid();
        }

        return winrt::guid(guid);
    }

    // Helper function to convert GattCharacteristicProperties to string for logging
    static std::string properties_to_string(GattCharacteristicProperties properties) {
        std::stringstream props;

        // 使用 std::underlying_type_t 获取枚举的底层类型
        using UnderlyingType = std::underlying_type_t<GattCharacteristicProperties>;
        const UnderlyingType propValue = static_cast<UnderlyingType>(properties);

        // 检查每个可能的属性并构建描述字符串
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::Broadcast)) props << "broadcast, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::Read)) props << "read, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::WriteWithoutResponse)) props << "writeWithoutResponse, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::Write)) props << "write, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::Notify)) props << "notify, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::Indicate)) props << "indicate, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::AuthenticatedSignedWrites)) props << "authenticatedSignedWrites, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::ReliableWrites)) props << "ReliableWrites, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::ExtendedProperties)) props << "extendedProperties, ";
        if (propValue & static_cast<UnderlyingType>(GattCharacteristicProperties::WritableAuxiliaries)) props << "WritableAuxiliaries, ";

        // 移除尾随的逗号和空格
        std::string result = props.str();
        if (!result.empty() && result.back() == ' ') {
            result.pop_back(); // Remove space
            if (!result.empty() && result.back() == ',') {
                result.pop_back(); // Remove comma
            }
        }

        // 如果没有任何属性设置，返回默认消息
        if (result.empty()) {
            return "No properties set";
        }

        return result;
    }

    static std::string to_hexstring(std::vector <uint8_t> bytes) {
        auto ss = std::stringstream();
        for (auto b: bytes)
            ss << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(b);
        return ss.str();
    }

    static std::string to_uuidstr(winrt::guid guid) {
        char chars[36 + 1];
        sprintf_s(chars, GUID_FORMAT, GUID_ARG(guid));
        return std::string{chars};
    }
    static winrt::hstring to_uuid_hstring(winrt::guid guid) {
        char chars[36 + 1];
        sprintf_s(chars, GUID_FORMAT, GUID_ARG(guid));
        return winrt::to_hstring(chars);
    }

    static uint64_t string_to_mac(std::string const &s) {
        unsigned char a[6];
        int last = -1;
        int rc = sscanf_s(s.c_str(), "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx%n",
                          a + 0, a + 1, a + 2, a + 3, a + 4, a + 5,
                          &last);
        if (rc != 6 || s.size() != last)
            throw std::runtime_error("invalid mac address format " + s);
        return
                uint64_t(a[0]) << 40 |
                uint64_t(a[1]) << 32 | (
                        // 32-bit instructions take fewer bytes on x86, so use them as much as possible.
                        uint32_t(a[2]) << 24 |
                        uint32_t(a[3]) << 16 |
                        uint32_t(a[4]) << 8 |
                        uint32_t(a[5])
                );
    }
    //解析制造商数据
    static std::vector <uint8_t> parseManufacturerData(BluetoothLEAdvertisement advertisement) {
        if (advertisement.ManufacturerData().Size() == 0)
            return std::vector<uint8_t>();

        auto manufacturerData = advertisement.ManufacturerData().GetAt(0);
        // FIXME Compat with REG_DWORD_BIG_ENDIAN
        uint8_t *prefix = uint16_t_union{manufacturerData.CompanyId()}.bytes;
        auto result = std::vector < uint8_t > {prefix, prefix + sizeof(uint16_t_union)};

        auto data = Utils::to_bytevc(manufacturerData.Data());
        result.insert(result.end(), data.begin(), data.end());
        return result;
    }
};


#endif // FLUTTER_BLUE_UTILS_H